<template>
  <vxe-toolbar>
    <template #buttons>
      <a-button :disabled="disabledBatchSetting" size="small" @click="handleOpenBatchSettingModal">批量设置</a-button>
    </template>
  </vxe-toolbar>

  <JVxeTable
    ref="tableRef"
    stripe
    keepSource
    rowSelection
    :toolbarConfig="toolbarConfig"
    :auto-resize="true" 
    :maxHeight="400"
    :checkboxConfig="{range: true}"
    :disabledRows="{ isPk: [true] }"
    :disabled="false"
    :columns="tableColums"
    :dataSource="skuData"
    @selectRowChange="handleSelectRowChange"
  >
    <template #stockSlot="{ row }">
      <a-button v-if="!isUpdate || getStoreStockTotal(row) === 0" type="link" class="mgt-stock" @click="handleOpenStoreStock(row)">管理库存</a-button>
      <span v-else class="mgt-stock-number">{{ getStoreStockTotal(row) }}</span>
    </template>
  </JVxeTable>
  <SkuStockSettingModel @register="registerBatchSettingModal" @success="handleBatchSettingSku" />
  <MgtSkuStockModal @register="registerMgtSkuStockModal" @success="handleUpdateStock" />
</template>
<script lang="ts" name="shop-goods-sku-stock" setup>
import { ref, onMounted, watch, computed, unref } from 'vue';
import { skuStockColumns } from './goods.data';
import { propTypes } from '/@/utils/propTypes';
import { VxeGridInstance } from 'vxe-table'
import { JVxeTypes, JVxeColumn } from '/@/components/jeecg/JVxeTable/types'
import { useModal } from '/@/components/Modal';
import MgtSkuStockModal from './MgtSkuStockModal.vue';
import SkuStockSettingModel from './SkuStockSettingModel.vue';
import { randomString } from '/@/utils/common/compUtils';
const [registerBatchSettingModal, { openModal: openBatchSettingModal }] = useModal();
const [registerMgtSkuStockModal, { openModal: openMgtSkuStockModal }] = useModal();
const toolbarConfig = ref({
  btns: [],
})
interface SkuData {
  id: string,
  tempId: string, // 随机生成
  stockList: string,
  weight: string,
  price: string
}
// key=规格id
const addColumns = ref<Map<string, JVxeColumn>>(new Map())
const dataSource = ref<Map<string, any>>(new Map())
const disabledBatchSetting = ref<boolean>(true)
const isInit = ref(false)
const props = defineProps({
  value: propTypes.array.def([]),
  // 选择的规格
  selectSpecList: propTypes.array.def([]),
  // 是否更新
  isUpdate: propTypes.bool.def(false)
})
const tableRef = ref<VxeGridInstance>()
const skuData = ref<SkuData[]>([])

const tableColums = computed(() => {
  let columns = Array.from(addColumns.value.values())
  columns = columns ? columns : []
  skuStockColumns.forEach(e => columns.push(e))
  return columns
})
const emit = defineEmits(['register', 'update:value']);
onMounted(() => {
  if (props.selectSpecList) {
    processSkuStockColumns(props.selectSpecList)
    processSkuStockData(props.selectSpecList)
  } 
})

watch(
  () => props.selectSpecList,
  (selectSpecList: any) => {
    processSkuStockColumns(selectSpecList)
    processSkuStockData(selectSpecList)
  },
  { deep: true }
)

/**
 * 处理sku库存的表列字段
 * @param selectSpec 选择的规格
 */
const processSkuStockColumns = (newSelectSpecList) => {
  console.log('newSelectSpecList', newSelectSpecList)
  const columns : JVxeColumn[] = []
  if (newSelectSpecList?.length === 0) {
    console.log('selectValue length is 0');
    addColumns.value.clear()
  } else {
    const deleteColumnSet : Set<string> = new Set()
    Array.from(addColumns.value.keys()).forEach(e => deleteColumnSet.add(e))
    newSelectSpecList.filter(e => e.specId && e.specId !== '' && e.values.length > 0).forEach(e => deleteColumnSet.delete(e.specId))

    const addColumnSet : Set<string> = new Set()
    newSelectSpecList.filter(e => e.specId && e.specId !== '' && e.values.length > 0).forEach(e => addColumnSet.add(e.specId))
    Array.from(addColumns.value.keys()).forEach(e => addColumnSet.delete(e))

    const tempMap = new Map()
    newSelectSpecList.forEach(e => tempMap.set(e.specId, e))

    deleteColumnSet.forEach(e => addColumns.value.delete(e))
    addColumnSet.forEach(specId => {
      const spec = tempMap.get(specId)
      addColumns.value.set(spec.specId, {
        title: spec.name,
        key: 'sku_' + spec.specId,
        type: JVxeTypes.normal,
        width: 80
      })
    })
  }
  
  Array.from(addColumns.value.values()).forEach(e => columns.push(e))
  skuStockColumns.forEach(e => columns.push(e))

}

/**
 * 处理sku库存的表数据
 * @param selectSpec 选择的规格
 */
const processSkuStockData = async (newSelectSpecList) => {
  dataSource.value.clear()
  newSelectSpecList.filter(e => e.specId !== '').forEach(e => dataSource.value.set(e.specId, e))

  let arr : any = []
  Array.from(dataSource.value.values()).forEach(spec => {
    const data = spec.values.map(value => ({...spec, value}))
    if (data.length > 0) {
      arr.push(data)
    }
    
  })

  let temp : any = []
  let resList : any[] = [] 
  /**
   * 【全排列算法】
   */
  let arrange = (arr, index = 0) => {
    if (arr.length === 0) {
      return
    }
    arr[index].forEach(item => {
      temp[index] = item
      index + 1 < arr.length ? arrange(arr, index + 1) : resList.push(temp.slice())
    })
  }
  arrange(arr)

  skuData.value = resList.map(e => {
    const data : any = {}
    data.tempId = randomString(16)
    const specData : any[] = []
    e.forEach(spec => {
      specData.push({
        key: spec.name,
        value: spec.value,
        specId: spec.specId
      })
      data['sku_' + spec.specId] = spec.value,
      data['weight'] = '0.00',
      data['price'] = '0.00',
      data['costPrice'] = '0.00',
      data['stockAlarm'] = '0',
      data['stockList'] = []
    })
    data['specData'] = specData
    return data
  })

  // 将传递的进来的数据转成map
  if (!isInit.value) {
    const oldVal : any[] = props.value || []
    const propsSkuMap : Map<any, any> = new Map()
    oldVal.forEach(e => propsSkuMap.set(e.specData.map(e1 => e1.value).sort().join('_'), e))

    const compSkuMap : Map<any, any> = new Map()
    skuData.value.forEach(e => compSkuMap.set(getCompSkuMapKey(e), e))
    
    const newSkuData : any[] = []
    // 遍历外部传递的sku数据
    propsSkuMap.forEach((e) => {
      const key = e.specData.map(e1 => e1.value).sort().join('_')
      newSkuData.push({...compSkuMap.get(key), ...e, })
    })
    
    if (newSkuData.length !== 0) {
      skuData.value = newSkuData
      console.log('newSkuData', newSkuData);
    }
    isInit.value = true
  }

  emit('update:value', unref(skuData))
}

const getCompSkuMapKey = (skuData : any[]) => {
  const resp : any[] = []
  for (const key in skuData) {
    if (key.includes('sku_')) {
      resp.push(skuData[key])
    }
  }
  return resp.sort().join('_')
}

const handleSelectRowChange = ({selectedRows}) => {
  disabledBatchSetting.value = selectedRows.length === 0
}

const handleOpenBatchSettingModal = () => {
  openBatchSettingModal(true, {})
}

/**
 * 批量设置sku
 * @param values 
 */
const handleBatchSettingSku = (values) => {
  console.log('values', values);
  const selectedData  = new Map()
  tableRef.value?.getSelectedData().forEach(e => selectedData.set(e.tempId, e))
  console.log('selectedData', selectedData, 'skuData', skuData.value);
  
  skuData.value = skuData.value.map(e => {
    if (selectedData.has(e.tempId)) {
      return { ...e, ...values }
    }
    return e
  })
  emit('update:value', unref(skuData))
}

/**
 * 更新库存信息
 */
const handleUpdateStock = (tempId, value) => {
  skuData.value = skuData.value.map(e => {
    if (e.tempId === tempId) {
      return { ...e, stockList: value }
    }
    return e
  })
  emit('update:value', unref(skuData))
}

const handleOpenStoreStock = (record) => {
  openMgtSkuStockModal(true, { record })
}

/**
 * 获取库存总数
 * @param record 
 */
const getStoreStockTotal = (record) => {
  let totalStock = 0
  record?.stockList.forEach(e => totalStock += e.stock)
  return totalStock
}

const getSkuStock = () => {
  const selectedData  = new Map()
  skuData.value = tableRef.value?.getTableData() as any[]
  console.log( 'skuData', skuData.value);
  for (const sku of skuData.value) {
    if (sku.id.startsWith('row_')) {
      sku.id = undefined
    }
  }
  emit('update:value', unref(skuData))
  return unref(skuData)
}
defineExpose({
  getSkuStock
})

</script>


<style lang="less">
.mgt-stock {
  margin-left: -15px;
}
.mgt-stock-number {
  margin-left: 5px;
}
</style>